/******************************************************************************/
/* This file is generated by the bin/template script and should not be        */
/* modified manually. See                                                     */
/* templates/src/serialize.c.erb                                              */
/* if you are looking to modify the                                           */
/* template                                                                   */
/******************************************************************************/
#include "yarp/ast.h"
#include "yarp/parser.h"
#include "yarp/util/yp_buffer.h"

#include <stdio.h>

static inline uint32_t
yp_long_to_u32(long value) {
    assert(value >= 0 && (unsigned long)value < UINT32_MAX);
    return (uint32_t) value;
}

static inline uint32_t
yp_ulong_to_u32(unsigned long value) {
    assert(value < UINT32_MAX);
    return (uint32_t) value;
}

static void
serialize_location(yp_parser_t *parser, yp_location_t *location, yp_buffer_t *buffer) {
    assert(location->start);
    assert(location->end);
    assert(location->start <= location->end);

    yp_buffer_append_u32(buffer, yp_long_to_u32(location->start - parser->start));
    yp_buffer_append_u32(buffer, yp_long_to_u32(location->end - location->start));
}

void
yp_serialize_node(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer) {
    yp_buffer_append_u8(buffer, node->type);

    size_t offset = buffer->length;

    serialize_location(parser, &node->location, buffer);

    switch (node->type) {
        case YP_NODE_ALIAS_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_alias_node_t *)node)->new_name, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_alias_node_t *)node)->old_name, buffer);
            serialize_location(parser, &((yp_alias_node_t *)node)->keyword_loc, buffer);
            break;
        }
        case YP_NODE_ALTERNATION_PATTERN_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_alternation_pattern_node_t *)node)->left, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_alternation_pattern_node_t *)node)->right, buffer);
            serialize_location(parser, &((yp_alternation_pattern_node_t *)node)->operator_loc, buffer);
            break;
        }
        case YP_NODE_AND_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_and_node_t *)node)->left, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_and_node_t *)node)->right, buffer);
            serialize_location(parser, &((yp_and_node_t *)node)->operator_loc, buffer);
            break;
        }
        case YP_NODE_ARGUMENTS_NODE: {
            uint32_t arguments_size = yp_ulong_to_u32(((yp_arguments_node_t *)node)->arguments.size);
            yp_buffer_append_u32(buffer, arguments_size);
            for (uint32_t index = 0; index < arguments_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_arguments_node_t *)node)->arguments.nodes[index], buffer);
            }
            break;
        }
        case YP_NODE_ARRAY_NODE: {
            uint32_t elements_size = yp_ulong_to_u32(((yp_array_node_t *)node)->elements.size);
            yp_buffer_append_u32(buffer, elements_size);
            for (uint32_t index = 0; index < elements_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_array_node_t *)node)->elements.nodes[index], buffer);
            }
            if (((yp_array_node_t *)node)->opening_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_array_node_t *)node)->opening_loc, buffer);
            }
            if (((yp_array_node_t *)node)->closing_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_array_node_t *)node)->closing_loc, buffer);
            }
            break;
        }
        case YP_NODE_ARRAY_PATTERN_NODE: {
            if (((yp_array_pattern_node_t *)node)->constant == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_array_pattern_node_t *)node)->constant, buffer);
            }
            uint32_t requireds_size = yp_ulong_to_u32(((yp_array_pattern_node_t *)node)->requireds.size);
            yp_buffer_append_u32(buffer, requireds_size);
            for (uint32_t index = 0; index < requireds_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_array_pattern_node_t *)node)->requireds.nodes[index], buffer);
            }
            if (((yp_array_pattern_node_t *)node)->rest == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_array_pattern_node_t *)node)->rest, buffer);
            }
            uint32_t posts_size = yp_ulong_to_u32(((yp_array_pattern_node_t *)node)->posts.size);
            yp_buffer_append_u32(buffer, posts_size);
            for (uint32_t index = 0; index < posts_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_array_pattern_node_t *)node)->posts.nodes[index], buffer);
            }
            if (((yp_array_pattern_node_t *)node)->opening_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_array_pattern_node_t *)node)->opening_loc, buffer);
            }
            if (((yp_array_pattern_node_t *)node)->closing_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_array_pattern_node_t *)node)->closing_loc, buffer);
            }
            break;
        }
        case YP_NODE_ASSOC_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_assoc_node_t *)node)->key, buffer);
            if (((yp_assoc_node_t *)node)->value == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_assoc_node_t *)node)->value, buffer);
            }
            if (((yp_assoc_node_t *)node)->operator_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_assoc_node_t *)node)->operator_loc, buffer);
            }
            break;
        }
        case YP_NODE_ASSOC_SPLAT_NODE: {
            if (((yp_assoc_splat_node_t *)node)->value == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_assoc_splat_node_t *)node)->value, buffer);
            }
            serialize_location(parser, &((yp_assoc_splat_node_t *)node)->operator_loc, buffer);
            break;
        }
        case YP_NODE_BACK_REFERENCE_READ_NODE: {
            break;
        }
        case YP_NODE_BEGIN_NODE: {
            if (((yp_begin_node_t *)node)->begin_keyword_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_begin_node_t *)node)->begin_keyword_loc, buffer);
            }
            if (((yp_begin_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_begin_node_t *)node)->statements, buffer);
            }
            if (((yp_begin_node_t *)node)->rescue_clause == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_begin_node_t *)node)->rescue_clause, buffer);
            }
            if (((yp_begin_node_t *)node)->else_clause == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_begin_node_t *)node)->else_clause, buffer);
            }
            if (((yp_begin_node_t *)node)->ensure_clause == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_begin_node_t *)node)->ensure_clause, buffer);
            }
            if (((yp_begin_node_t *)node)->end_keyword_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_begin_node_t *)node)->end_keyword_loc, buffer);
            }
            break;
        }
        case YP_NODE_BLOCK_ARGUMENT_NODE: {
            if (((yp_block_argument_node_t *)node)->expression == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_block_argument_node_t *)node)->expression, buffer);
            }
            serialize_location(parser, &((yp_block_argument_node_t *)node)->operator_loc, buffer);
            break;
        }
        case YP_NODE_BLOCK_NODE: {
            uint32_t locals_size = yp_ulong_to_u32(((yp_block_node_t *)node)->locals.size);
            yp_buffer_append_u32(buffer, locals_size);
            for (uint32_t index = 0; index < locals_size; index++) {
                yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_block_node_t *)node)->locals.ids[index]));
            }
            if (((yp_block_node_t *)node)->parameters == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_block_node_t *)node)->parameters, buffer);
            }
            if (((yp_block_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_block_node_t *)node)->statements, buffer);
            }
            serialize_location(parser, &((yp_block_node_t *)node)->opening_loc, buffer);
            serialize_location(parser, &((yp_block_node_t *)node)->closing_loc, buffer);
            break;
        }
        case YP_NODE_BLOCK_PARAMETER_NODE: {
            if (((yp_block_parameter_node_t *)node)->name_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_block_parameter_node_t *)node)->name_loc, buffer);
            }
            serialize_location(parser, &((yp_block_parameter_node_t *)node)->operator_loc, buffer);
            break;
        }
        case YP_NODE_BLOCK_PARAMETERS_NODE: {
            if (((yp_block_parameters_node_t *)node)->parameters == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_block_parameters_node_t *)node)->parameters, buffer);
            }
            uint32_t locals_size = yp_ulong_to_u32(((yp_block_parameters_node_t *)node)->locals.size);
            yp_buffer_append_u32(buffer, locals_size);
            for (uint32_t index = 0; index < locals_size; index++) {
                serialize_location(parser, &((yp_block_parameters_node_t *)node)->locals.locations[index], buffer);
            }
            if (((yp_block_parameters_node_t *)node)->opening_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_block_parameters_node_t *)node)->opening_loc, buffer);
            }
            if (((yp_block_parameters_node_t *)node)->closing_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_block_parameters_node_t *)node)->closing_loc, buffer);
            }
            break;
        }
        case YP_NODE_BREAK_NODE: {
            if (((yp_break_node_t *)node)->arguments == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_break_node_t *)node)->arguments, buffer);
            }
            serialize_location(parser, &((yp_break_node_t *)node)->keyword_loc, buffer);
            break;
        }
        case YP_NODE_CALL_NODE: {
            if (((yp_call_node_t *)node)->receiver == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_call_node_t *)node)->receiver, buffer);
            }
            if (((yp_call_node_t *)node)->operator_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_call_node_t *)node)->operator_loc, buffer);
            }
            if (((yp_call_node_t *)node)->message_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_call_node_t *)node)->message_loc, buffer);
            }
            if (((yp_call_node_t *)node)->opening_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_call_node_t *)node)->opening_loc, buffer);
            }
            if (((yp_call_node_t *)node)->arguments == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_call_node_t *)node)->arguments, buffer);
            }
            if (((yp_call_node_t *)node)->closing_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_call_node_t *)node)->closing_loc, buffer);
            }
            if (((yp_call_node_t *)node)->block == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_call_node_t *)node)->block, buffer);
            }
            yp_buffer_append_u32(buffer, ((yp_call_node_t *)node)->flags);
            uint32_t name_length = yp_ulong_to_u32(yp_string_length(&((yp_call_node_t *)node)->name));
            yp_buffer_append_u32(buffer, name_length);
            yp_buffer_append_str(buffer, yp_string_source(&((yp_call_node_t *)node)->name), name_length);
            break;
        }
        case YP_NODE_CALL_OPERATOR_AND_WRITE_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_call_operator_and_write_node_t *)node)->target, buffer);
            serialize_location(parser, &((yp_call_operator_and_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_call_operator_and_write_node_t *)node)->value, buffer);
            break;
        }
        case YP_NODE_CALL_OPERATOR_OR_WRITE_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_call_operator_or_write_node_t *)node)->target, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_call_operator_or_write_node_t *)node)->value, buffer);
            serialize_location(parser, &((yp_call_operator_or_write_node_t *)node)->operator_loc, buffer);
            break;
        }
        case YP_NODE_CALL_OPERATOR_WRITE_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_call_operator_write_node_t *)node)->target, buffer);
            serialize_location(parser, &((yp_call_operator_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_call_operator_write_node_t *)node)->value, buffer);
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_call_operator_write_node_t *)node)->operator_id));
            break;
        }
        case YP_NODE_CAPTURE_PATTERN_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_capture_pattern_node_t *)node)->value, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_capture_pattern_node_t *)node)->target, buffer);
            serialize_location(parser, &((yp_capture_pattern_node_t *)node)->operator_loc, buffer);
            break;
        }
        case YP_NODE_CASE_NODE: {
            if (((yp_case_node_t *)node)->predicate == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_case_node_t *)node)->predicate, buffer);
            }
            uint32_t conditions_size = yp_ulong_to_u32(((yp_case_node_t *)node)->conditions.size);
            yp_buffer_append_u32(buffer, conditions_size);
            for (uint32_t index = 0; index < conditions_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_case_node_t *)node)->conditions.nodes[index], buffer);
            }
            if (((yp_case_node_t *)node)->consequent == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_case_node_t *)node)->consequent, buffer);
            }
            serialize_location(parser, &((yp_case_node_t *)node)->case_keyword_loc, buffer);
            serialize_location(parser, &((yp_case_node_t *)node)->end_keyword_loc, buffer);
            break;
        }
        case YP_NODE_CLASS_NODE: {
            uint32_t locals_size = yp_ulong_to_u32(((yp_class_node_t *)node)->locals.size);
            yp_buffer_append_u32(buffer, locals_size);
            for (uint32_t index = 0; index < locals_size; index++) {
                yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_class_node_t *)node)->locals.ids[index]));
            }
            serialize_location(parser, &((yp_class_node_t *)node)->class_keyword_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_class_node_t *)node)->constant_path, buffer);
            if (((yp_class_node_t *)node)->inheritance_operator_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_class_node_t *)node)->inheritance_operator_loc, buffer);
            }
            if (((yp_class_node_t *)node)->superclass == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_class_node_t *)node)->superclass, buffer);
            }
            if (((yp_class_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_class_node_t *)node)->statements, buffer);
            }
            serialize_location(parser, &((yp_class_node_t *)node)->end_keyword_loc, buffer);
            break;
        }
        case YP_NODE_CLASS_VARIABLE_OPERATOR_AND_WRITE_NODE: {
            serialize_location(parser, &((yp_class_variable_operator_and_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_class_variable_operator_and_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_class_variable_operator_and_write_node_t *)node)->value, buffer);
            break;
        }
        case YP_NODE_CLASS_VARIABLE_OPERATOR_OR_WRITE_NODE: {
            serialize_location(parser, &((yp_class_variable_operator_or_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_class_variable_operator_or_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_class_variable_operator_or_write_node_t *)node)->value, buffer);
            break;
        }
        case YP_NODE_CLASS_VARIABLE_OPERATOR_WRITE_NODE: {
            serialize_location(parser, &((yp_class_variable_operator_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_class_variable_operator_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_class_variable_operator_write_node_t *)node)->value, buffer);
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_class_variable_operator_write_node_t *)node)->operator));
            break;
        }
        case YP_NODE_CLASS_VARIABLE_READ_NODE: {
            break;
        }
        case YP_NODE_CLASS_VARIABLE_WRITE_NODE: {
            serialize_location(parser, &((yp_class_variable_write_node_t *)node)->name_loc, buffer);
            if (((yp_class_variable_write_node_t *)node)->value == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_class_variable_write_node_t *)node)->value, buffer);
            }
            if (((yp_class_variable_write_node_t *)node)->operator_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_class_variable_write_node_t *)node)->operator_loc, buffer);
            }
            break;
        }
        case YP_NODE_CONSTANT_OPERATOR_AND_WRITE_NODE: {
            serialize_location(parser, &((yp_constant_operator_and_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_constant_operator_and_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_constant_operator_and_write_node_t *)node)->value, buffer);
            break;
        }
        case YP_NODE_CONSTANT_OPERATOR_OR_WRITE_NODE: {
            serialize_location(parser, &((yp_constant_operator_or_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_constant_operator_or_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_constant_operator_or_write_node_t *)node)->value, buffer);
            break;
        }
        case YP_NODE_CONSTANT_OPERATOR_WRITE_NODE: {
            serialize_location(parser, &((yp_constant_operator_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_constant_operator_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_constant_operator_write_node_t *)node)->value, buffer);
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_constant_operator_write_node_t *)node)->operator));
            break;
        }
        case YP_NODE_CONSTANT_PATH_NODE: {
            if (((yp_constant_path_node_t *)node)->parent == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_constant_path_node_t *)node)->parent, buffer);
            }
            yp_serialize_node(parser, (yp_node_t *)((yp_constant_path_node_t *)node)->child, buffer);
            serialize_location(parser, &((yp_constant_path_node_t *)node)->delimiter_loc, buffer);
            break;
        }
        case YP_NODE_CONSTANT_PATH_OPERATOR_AND_WRITE_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_constant_path_operator_and_write_node_t *)node)->target, buffer);
            serialize_location(parser, &((yp_constant_path_operator_and_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_constant_path_operator_and_write_node_t *)node)->value, buffer);
            break;
        }
        case YP_NODE_CONSTANT_PATH_OPERATOR_OR_WRITE_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_constant_path_operator_or_write_node_t *)node)->target, buffer);
            serialize_location(parser, &((yp_constant_path_operator_or_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_constant_path_operator_or_write_node_t *)node)->value, buffer);
            break;
        }
        case YP_NODE_CONSTANT_PATH_OPERATOR_WRITE_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_constant_path_operator_write_node_t *)node)->target, buffer);
            serialize_location(parser, &((yp_constant_path_operator_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_constant_path_operator_write_node_t *)node)->value, buffer);
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_constant_path_operator_write_node_t *)node)->operator));
            break;
        }
        case YP_NODE_CONSTANT_PATH_WRITE_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_constant_path_write_node_t *)node)->target, buffer);
            if (((yp_constant_path_write_node_t *)node)->operator_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_constant_path_write_node_t *)node)->operator_loc, buffer);
            }
            if (((yp_constant_path_write_node_t *)node)->value == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_constant_path_write_node_t *)node)->value, buffer);
            }
            break;
        }
        case YP_NODE_CONSTANT_READ_NODE: {
            break;
        }
        case YP_NODE_DEF_NODE: {
                // serialize length
                // encoding of location u32s make us need to save this offset.
                size_t length_offset = buffer->length;
                yp_buffer_append_str(buffer, "\0\0\0\0", 4); /* consume 4 bytes, updated below */
            serialize_location(parser, &((yp_def_node_t *)node)->name_loc, buffer);
            if (((yp_def_node_t *)node)->receiver == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_def_node_t *)node)->receiver, buffer);
            }
            if (((yp_def_node_t *)node)->parameters == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_def_node_t *)node)->parameters, buffer);
            }
            if (((yp_def_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_def_node_t *)node)->statements, buffer);
            }
            uint32_t locals_size = yp_ulong_to_u32(((yp_def_node_t *)node)->locals.size);
            yp_buffer_append_u32(buffer, locals_size);
            for (uint32_t index = 0; index < locals_size; index++) {
                yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_def_node_t *)node)->locals.ids[index]));
            }
            serialize_location(parser, &((yp_def_node_t *)node)->def_keyword_loc, buffer);
            if (((yp_def_node_t *)node)->operator_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_def_node_t *)node)->operator_loc, buffer);
            }
            if (((yp_def_node_t *)node)->lparen_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_def_node_t *)node)->lparen_loc, buffer);
            }
            if (((yp_def_node_t *)node)->rparen_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_def_node_t *)node)->rparen_loc, buffer);
            }
            if (((yp_def_node_t *)node)->equal_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_def_node_t *)node)->equal_loc, buffer);
            }
            if (((yp_def_node_t *)node)->end_keyword_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_def_node_t *)node)->end_keyword_loc, buffer);
            }
                // serialize length
                uint32_t length = yp_ulong_to_u32(buffer->length - offset - sizeof(uint32_t));
                memcpy(buffer->value + length_offset, &length, sizeof(uint32_t));
            break;
        }
        case YP_NODE_DEFINED_NODE: {
            if (((yp_defined_node_t *)node)->lparen_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_defined_node_t *)node)->lparen_loc, buffer);
            }
            yp_serialize_node(parser, (yp_node_t *)((yp_defined_node_t *)node)->value, buffer);
            if (((yp_defined_node_t *)node)->rparen_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_defined_node_t *)node)->rparen_loc, buffer);
            }
            serialize_location(parser, &((yp_defined_node_t *)node)->keyword_loc, buffer);
            break;
        }
        case YP_NODE_ELSE_NODE: {
            serialize_location(parser, &((yp_else_node_t *)node)->else_keyword_loc, buffer);
            if (((yp_else_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_else_node_t *)node)->statements, buffer);
            }
            if (((yp_else_node_t *)node)->end_keyword_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_else_node_t *)node)->end_keyword_loc, buffer);
            }
            break;
        }
        case YP_NODE_EMBEDDED_STATEMENTS_NODE: {
            serialize_location(parser, &((yp_embedded_statements_node_t *)node)->opening_loc, buffer);
            if (((yp_embedded_statements_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_embedded_statements_node_t *)node)->statements, buffer);
            }
            serialize_location(parser, &((yp_embedded_statements_node_t *)node)->closing_loc, buffer);
            break;
        }
        case YP_NODE_EMBEDDED_VARIABLE_NODE: {
            serialize_location(parser, &((yp_embedded_variable_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_embedded_variable_node_t *)node)->variable, buffer);
            break;
        }
        case YP_NODE_ENSURE_NODE: {
            serialize_location(parser, &((yp_ensure_node_t *)node)->ensure_keyword_loc, buffer);
            if (((yp_ensure_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_ensure_node_t *)node)->statements, buffer);
            }
            serialize_location(parser, &((yp_ensure_node_t *)node)->end_keyword_loc, buffer);
            break;
        }
        case YP_NODE_FALSE_NODE: {
            break;
        }
        case YP_NODE_FIND_PATTERN_NODE: {
            if (((yp_find_pattern_node_t *)node)->constant == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_find_pattern_node_t *)node)->constant, buffer);
            }
            yp_serialize_node(parser, (yp_node_t *)((yp_find_pattern_node_t *)node)->left, buffer);
            uint32_t requireds_size = yp_ulong_to_u32(((yp_find_pattern_node_t *)node)->requireds.size);
            yp_buffer_append_u32(buffer, requireds_size);
            for (uint32_t index = 0; index < requireds_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_find_pattern_node_t *)node)->requireds.nodes[index], buffer);
            }
            yp_serialize_node(parser, (yp_node_t *)((yp_find_pattern_node_t *)node)->right, buffer);
            if (((yp_find_pattern_node_t *)node)->opening_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_find_pattern_node_t *)node)->opening_loc, buffer);
            }
            if (((yp_find_pattern_node_t *)node)->closing_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_find_pattern_node_t *)node)->closing_loc, buffer);
            }
            break;
        }
        case YP_NODE_FLOAT_NODE: {
            break;
        }
        case YP_NODE_FOR_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_for_node_t *)node)->index, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_for_node_t *)node)->collection, buffer);
            if (((yp_for_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_for_node_t *)node)->statements, buffer);
            }
            serialize_location(parser, &((yp_for_node_t *)node)->for_keyword_loc, buffer);
            serialize_location(parser, &((yp_for_node_t *)node)->in_keyword_loc, buffer);
            if (((yp_for_node_t *)node)->do_keyword_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_for_node_t *)node)->do_keyword_loc, buffer);
            }
            serialize_location(parser, &((yp_for_node_t *)node)->end_keyword_loc, buffer);
            break;
        }
        case YP_NODE_FORWARDING_ARGUMENTS_NODE: {
            break;
        }
        case YP_NODE_FORWARDING_PARAMETER_NODE: {
            break;
        }
        case YP_NODE_FORWARDING_SUPER_NODE: {
            if (((yp_forwarding_super_node_t *)node)->block == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_forwarding_super_node_t *)node)->block, buffer);
            }
            break;
        }
        case YP_NODE_GLOBAL_VARIABLE_OPERATOR_AND_WRITE_NODE: {
            serialize_location(parser, &((yp_global_variable_operator_and_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_global_variable_operator_and_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_global_variable_operator_and_write_node_t *)node)->value, buffer);
            break;
        }
        case YP_NODE_GLOBAL_VARIABLE_OPERATOR_OR_WRITE_NODE: {
            serialize_location(parser, &((yp_global_variable_operator_or_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_global_variable_operator_or_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_global_variable_operator_or_write_node_t *)node)->value, buffer);
            break;
        }
        case YP_NODE_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: {
            serialize_location(parser, &((yp_global_variable_operator_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_global_variable_operator_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_global_variable_operator_write_node_t *)node)->value, buffer);
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_global_variable_operator_write_node_t *)node)->operator));
            break;
        }
        case YP_NODE_GLOBAL_VARIABLE_READ_NODE: {
            break;
        }
        case YP_NODE_GLOBAL_VARIABLE_WRITE_NODE: {
            serialize_location(parser, &((yp_global_variable_write_node_t *)node)->name_loc, buffer);
            if (((yp_global_variable_write_node_t *)node)->operator_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_global_variable_write_node_t *)node)->operator_loc, buffer);
            }
            if (((yp_global_variable_write_node_t *)node)->value == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_global_variable_write_node_t *)node)->value, buffer);
            }
            break;
        }
        case YP_NODE_HASH_NODE: {
            serialize_location(parser, &((yp_hash_node_t *)node)->opening_loc, buffer);
            uint32_t elements_size = yp_ulong_to_u32(((yp_hash_node_t *)node)->elements.size);
            yp_buffer_append_u32(buffer, elements_size);
            for (uint32_t index = 0; index < elements_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_hash_node_t *)node)->elements.nodes[index], buffer);
            }
            serialize_location(parser, &((yp_hash_node_t *)node)->closing_loc, buffer);
            break;
        }
        case YP_NODE_HASH_PATTERN_NODE: {
            if (((yp_hash_pattern_node_t *)node)->constant == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_hash_pattern_node_t *)node)->constant, buffer);
            }
            uint32_t assocs_size = yp_ulong_to_u32(((yp_hash_pattern_node_t *)node)->assocs.size);
            yp_buffer_append_u32(buffer, assocs_size);
            for (uint32_t index = 0; index < assocs_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_hash_pattern_node_t *)node)->assocs.nodes[index], buffer);
            }
            if (((yp_hash_pattern_node_t *)node)->kwrest == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_hash_pattern_node_t *)node)->kwrest, buffer);
            }
            if (((yp_hash_pattern_node_t *)node)->opening_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_hash_pattern_node_t *)node)->opening_loc, buffer);
            }
            if (((yp_hash_pattern_node_t *)node)->closing_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_hash_pattern_node_t *)node)->closing_loc, buffer);
            }
            break;
        }
        case YP_NODE_IF_NODE: {
            if (((yp_if_node_t *)node)->if_keyword_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_if_node_t *)node)->if_keyword_loc, buffer);
            }
            yp_serialize_node(parser, (yp_node_t *)((yp_if_node_t *)node)->predicate, buffer);
            if (((yp_if_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_if_node_t *)node)->statements, buffer);
            }
            if (((yp_if_node_t *)node)->consequent == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_if_node_t *)node)->consequent, buffer);
            }
            if (((yp_if_node_t *)node)->end_keyword_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_if_node_t *)node)->end_keyword_loc, buffer);
            }
            break;
        }
        case YP_NODE_IMAGINARY_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_imaginary_node_t *)node)->numeric, buffer);
            break;
        }
        case YP_NODE_IN_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_in_node_t *)node)->pattern, buffer);
            if (((yp_in_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_in_node_t *)node)->statements, buffer);
            }
            serialize_location(parser, &((yp_in_node_t *)node)->in_loc, buffer);
            if (((yp_in_node_t *)node)->then_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_in_node_t *)node)->then_loc, buffer);
            }
            break;
        }
        case YP_NODE_INSTANCE_VARIABLE_OPERATOR_AND_WRITE_NODE: {
            serialize_location(parser, &((yp_instance_variable_operator_and_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_instance_variable_operator_and_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_instance_variable_operator_and_write_node_t *)node)->value, buffer);
            break;
        }
        case YP_NODE_INSTANCE_VARIABLE_OPERATOR_OR_WRITE_NODE: {
            serialize_location(parser, &((yp_instance_variable_operator_or_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_instance_variable_operator_or_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_instance_variable_operator_or_write_node_t *)node)->value, buffer);
            break;
        }
        case YP_NODE_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: {
            serialize_location(parser, &((yp_instance_variable_operator_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_instance_variable_operator_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_instance_variable_operator_write_node_t *)node)->value, buffer);
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_instance_variable_operator_write_node_t *)node)->operator));
            break;
        }
        case YP_NODE_INSTANCE_VARIABLE_READ_NODE: {
            break;
        }
        case YP_NODE_INSTANCE_VARIABLE_WRITE_NODE: {
            serialize_location(parser, &((yp_instance_variable_write_node_t *)node)->name_loc, buffer);
            if (((yp_instance_variable_write_node_t *)node)->value == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_instance_variable_write_node_t *)node)->value, buffer);
            }
            if (((yp_instance_variable_write_node_t *)node)->operator_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_instance_variable_write_node_t *)node)->operator_loc, buffer);
            }
            break;
        }
        case YP_NODE_INTEGER_NODE: {
            break;
        }
        case YP_NODE_INTERPOLATED_REGULAR_EXPRESSION_NODE: {
            serialize_location(parser, &((yp_interpolated_regular_expression_node_t *)node)->opening_loc, buffer);
            uint32_t parts_size = yp_ulong_to_u32(((yp_interpolated_regular_expression_node_t *)node)->parts.size);
            yp_buffer_append_u32(buffer, parts_size);
            for (uint32_t index = 0; index < parts_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_interpolated_regular_expression_node_t *)node)->parts.nodes[index], buffer);
            }
            serialize_location(parser, &((yp_interpolated_regular_expression_node_t *)node)->closing_loc, buffer);
            yp_buffer_append_u32(buffer, ((yp_interpolated_regular_expression_node_t *)node)->flags);
            break;
        }
        case YP_NODE_INTERPOLATED_STRING_NODE: {
            if (((yp_interpolated_string_node_t *)node)->opening_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_interpolated_string_node_t *)node)->opening_loc, buffer);
            }
            uint32_t parts_size = yp_ulong_to_u32(((yp_interpolated_string_node_t *)node)->parts.size);
            yp_buffer_append_u32(buffer, parts_size);
            for (uint32_t index = 0; index < parts_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_interpolated_string_node_t *)node)->parts.nodes[index], buffer);
            }
            if (((yp_interpolated_string_node_t *)node)->closing_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_interpolated_string_node_t *)node)->closing_loc, buffer);
            }
            break;
        }
        case YP_NODE_INTERPOLATED_SYMBOL_NODE: {
            if (((yp_interpolated_symbol_node_t *)node)->opening_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_interpolated_symbol_node_t *)node)->opening_loc, buffer);
            }
            uint32_t parts_size = yp_ulong_to_u32(((yp_interpolated_symbol_node_t *)node)->parts.size);
            yp_buffer_append_u32(buffer, parts_size);
            for (uint32_t index = 0; index < parts_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_interpolated_symbol_node_t *)node)->parts.nodes[index], buffer);
            }
            if (((yp_interpolated_symbol_node_t *)node)->closing_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_interpolated_symbol_node_t *)node)->closing_loc, buffer);
            }
            break;
        }
        case YP_NODE_INTERPOLATED_X_STRING_NODE: {
            serialize_location(parser, &((yp_interpolated_x_string_node_t *)node)->opening_loc, buffer);
            uint32_t parts_size = yp_ulong_to_u32(((yp_interpolated_x_string_node_t *)node)->parts.size);
            yp_buffer_append_u32(buffer, parts_size);
            for (uint32_t index = 0; index < parts_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_interpolated_x_string_node_t *)node)->parts.nodes[index], buffer);
            }
            serialize_location(parser, &((yp_interpolated_x_string_node_t *)node)->closing_loc, buffer);
            break;
        }
        case YP_NODE_KEYWORD_HASH_NODE: {
            uint32_t elements_size = yp_ulong_to_u32(((yp_keyword_hash_node_t *)node)->elements.size);
            yp_buffer_append_u32(buffer, elements_size);
            for (uint32_t index = 0; index < elements_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_keyword_hash_node_t *)node)->elements.nodes[index], buffer);
            }
            break;
        }
        case YP_NODE_KEYWORD_PARAMETER_NODE: {
            serialize_location(parser, &((yp_keyword_parameter_node_t *)node)->name_loc, buffer);
            if (((yp_keyword_parameter_node_t *)node)->value == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_keyword_parameter_node_t *)node)->value, buffer);
            }
            break;
        }
        case YP_NODE_KEYWORD_REST_PARAMETER_NODE: {
            serialize_location(parser, &((yp_keyword_rest_parameter_node_t *)node)->operator_loc, buffer);
            if (((yp_keyword_rest_parameter_node_t *)node)->name_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_keyword_rest_parameter_node_t *)node)->name_loc, buffer);
            }
            break;
        }
        case YP_NODE_LAMBDA_NODE: {
            uint32_t locals_size = yp_ulong_to_u32(((yp_lambda_node_t *)node)->locals.size);
            yp_buffer_append_u32(buffer, locals_size);
            for (uint32_t index = 0; index < locals_size; index++) {
                yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_lambda_node_t *)node)->locals.ids[index]));
            }
            serialize_location(parser, &((yp_lambda_node_t *)node)->opening_loc, buffer);
            if (((yp_lambda_node_t *)node)->parameters == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_lambda_node_t *)node)->parameters, buffer);
            }
            if (((yp_lambda_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_lambda_node_t *)node)->statements, buffer);
            }
            break;
        }
        case YP_NODE_LOCAL_VARIABLE_OPERATOR_AND_WRITE_NODE: {
            serialize_location(parser, &((yp_local_variable_operator_and_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_local_variable_operator_and_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_local_variable_operator_and_write_node_t *)node)->value, buffer);
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_local_variable_operator_and_write_node_t *)node)->constant_id));
            break;
        }
        case YP_NODE_LOCAL_VARIABLE_OPERATOR_OR_WRITE_NODE: {
            serialize_location(parser, &((yp_local_variable_operator_or_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_local_variable_operator_or_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_local_variable_operator_or_write_node_t *)node)->value, buffer);
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_local_variable_operator_or_write_node_t *)node)->constant_id));
            break;
        }
        case YP_NODE_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: {
            serialize_location(parser, &((yp_local_variable_operator_write_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_local_variable_operator_write_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_local_variable_operator_write_node_t *)node)->value, buffer);
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_local_variable_operator_write_node_t *)node)->constant_id));
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_local_variable_operator_write_node_t *)node)->operator_id));
            break;
        }
        case YP_NODE_LOCAL_VARIABLE_READ_NODE: {
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_local_variable_read_node_t *)node)->constant_id));
            yp_buffer_append_u32(buffer, ((yp_local_variable_read_node_t *)node)->depth);
            break;
        }
        case YP_NODE_LOCAL_VARIABLE_WRITE_NODE: {
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_local_variable_write_node_t *)node)->constant_id));
            yp_buffer_append_u32(buffer, ((yp_local_variable_write_node_t *)node)->depth);
            if (((yp_local_variable_write_node_t *)node)->value == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_local_variable_write_node_t *)node)->value, buffer);
            }
            serialize_location(parser, &((yp_local_variable_write_node_t *)node)->name_loc, buffer);
            if (((yp_local_variable_write_node_t *)node)->operator_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_local_variable_write_node_t *)node)->operator_loc, buffer);
            }
            break;
        }
        case YP_NODE_MATCH_PREDICATE_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_match_predicate_node_t *)node)->value, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_match_predicate_node_t *)node)->pattern, buffer);
            serialize_location(parser, &((yp_match_predicate_node_t *)node)->operator_loc, buffer);
            break;
        }
        case YP_NODE_MATCH_REQUIRED_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_match_required_node_t *)node)->value, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_match_required_node_t *)node)->pattern, buffer);
            serialize_location(parser, &((yp_match_required_node_t *)node)->operator_loc, buffer);
            break;
        }
        case YP_NODE_MISSING_NODE: {
            break;
        }
        case YP_NODE_MODULE_NODE: {
            uint32_t locals_size = yp_ulong_to_u32(((yp_module_node_t *)node)->locals.size);
            yp_buffer_append_u32(buffer, locals_size);
            for (uint32_t index = 0; index < locals_size; index++) {
                yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_module_node_t *)node)->locals.ids[index]));
            }
            serialize_location(parser, &((yp_module_node_t *)node)->module_keyword_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_module_node_t *)node)->constant_path, buffer);
            if (((yp_module_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_module_node_t *)node)->statements, buffer);
            }
            serialize_location(parser, &((yp_module_node_t *)node)->end_keyword_loc, buffer);
            break;
        }
        case YP_NODE_MULTI_WRITE_NODE: {
            uint32_t targets_size = yp_ulong_to_u32(((yp_multi_write_node_t *)node)->targets.size);
            yp_buffer_append_u32(buffer, targets_size);
            for (uint32_t index = 0; index < targets_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_multi_write_node_t *)node)->targets.nodes[index], buffer);
            }
            if (((yp_multi_write_node_t *)node)->operator_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_multi_write_node_t *)node)->operator_loc, buffer);
            }
            if (((yp_multi_write_node_t *)node)->value == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_multi_write_node_t *)node)->value, buffer);
            }
            if (((yp_multi_write_node_t *)node)->lparen_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_multi_write_node_t *)node)->lparen_loc, buffer);
            }
            if (((yp_multi_write_node_t *)node)->rparen_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_multi_write_node_t *)node)->rparen_loc, buffer);
            }
            break;
        }
        case YP_NODE_NEXT_NODE: {
            if (((yp_next_node_t *)node)->arguments == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_next_node_t *)node)->arguments, buffer);
            }
            serialize_location(parser, &((yp_next_node_t *)node)->keyword_loc, buffer);
            break;
        }
        case YP_NODE_NIL_NODE: {
            break;
        }
        case YP_NODE_NO_KEYWORDS_PARAMETER_NODE: {
            serialize_location(parser, &((yp_no_keywords_parameter_node_t *)node)->operator_loc, buffer);
            serialize_location(parser, &((yp_no_keywords_parameter_node_t *)node)->keyword_loc, buffer);
            break;
        }
        case YP_NODE_NUMBERED_REFERENCE_READ_NODE: {
            break;
        }
        case YP_NODE_OPTIONAL_PARAMETER_NODE: {
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_optional_parameter_node_t *)node)->constant_id));
            serialize_location(parser, &((yp_optional_parameter_node_t *)node)->name_loc, buffer);
            serialize_location(parser, &((yp_optional_parameter_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_optional_parameter_node_t *)node)->value, buffer);
            break;
        }
        case YP_NODE_OR_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_or_node_t *)node)->left, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_or_node_t *)node)->right, buffer);
            serialize_location(parser, &((yp_or_node_t *)node)->operator_loc, buffer);
            break;
        }
        case YP_NODE_PARAMETERS_NODE: {
            uint32_t requireds_size = yp_ulong_to_u32(((yp_parameters_node_t *)node)->requireds.size);
            yp_buffer_append_u32(buffer, requireds_size);
            for (uint32_t index = 0; index < requireds_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_parameters_node_t *)node)->requireds.nodes[index], buffer);
            }
            uint32_t optionals_size = yp_ulong_to_u32(((yp_parameters_node_t *)node)->optionals.size);
            yp_buffer_append_u32(buffer, optionals_size);
            for (uint32_t index = 0; index < optionals_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_parameters_node_t *)node)->optionals.nodes[index], buffer);
            }
            uint32_t posts_size = yp_ulong_to_u32(((yp_parameters_node_t *)node)->posts.size);
            yp_buffer_append_u32(buffer, posts_size);
            for (uint32_t index = 0; index < posts_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_parameters_node_t *)node)->posts.nodes[index], buffer);
            }
            if (((yp_parameters_node_t *)node)->rest == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_parameters_node_t *)node)->rest, buffer);
            }
            uint32_t keywords_size = yp_ulong_to_u32(((yp_parameters_node_t *)node)->keywords.size);
            yp_buffer_append_u32(buffer, keywords_size);
            for (uint32_t index = 0; index < keywords_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_parameters_node_t *)node)->keywords.nodes[index], buffer);
            }
            if (((yp_parameters_node_t *)node)->keyword_rest == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_parameters_node_t *)node)->keyword_rest, buffer);
            }
            if (((yp_parameters_node_t *)node)->block == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_parameters_node_t *)node)->block, buffer);
            }
            break;
        }
        case YP_NODE_PARENTHESES_NODE: {
            if (((yp_parentheses_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_parentheses_node_t *)node)->statements, buffer);
            }
            serialize_location(parser, &((yp_parentheses_node_t *)node)->opening_loc, buffer);
            serialize_location(parser, &((yp_parentheses_node_t *)node)->closing_loc, buffer);
            break;
        }
        case YP_NODE_PINNED_EXPRESSION_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_pinned_expression_node_t *)node)->expression, buffer);
            serialize_location(parser, &((yp_pinned_expression_node_t *)node)->operator_loc, buffer);
            serialize_location(parser, &((yp_pinned_expression_node_t *)node)->lparen_loc, buffer);
            serialize_location(parser, &((yp_pinned_expression_node_t *)node)->rparen_loc, buffer);
            break;
        }
        case YP_NODE_PINNED_VARIABLE_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_pinned_variable_node_t *)node)->variable, buffer);
            serialize_location(parser, &((yp_pinned_variable_node_t *)node)->operator_loc, buffer);
            break;
        }
        case YP_NODE_POST_EXECUTION_NODE: {
            if (((yp_post_execution_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_post_execution_node_t *)node)->statements, buffer);
            }
            serialize_location(parser, &((yp_post_execution_node_t *)node)->keyword_loc, buffer);
            serialize_location(parser, &((yp_post_execution_node_t *)node)->opening_loc, buffer);
            serialize_location(parser, &((yp_post_execution_node_t *)node)->closing_loc, buffer);
            break;
        }
        case YP_NODE_PRE_EXECUTION_NODE: {
            if (((yp_pre_execution_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_pre_execution_node_t *)node)->statements, buffer);
            }
            serialize_location(parser, &((yp_pre_execution_node_t *)node)->keyword_loc, buffer);
            serialize_location(parser, &((yp_pre_execution_node_t *)node)->opening_loc, buffer);
            serialize_location(parser, &((yp_pre_execution_node_t *)node)->closing_loc, buffer);
            break;
        }
        case YP_NODE_PROGRAM_NODE: {
            uint32_t locals_size = yp_ulong_to_u32(((yp_program_node_t *)node)->locals.size);
            yp_buffer_append_u32(buffer, locals_size);
            for (uint32_t index = 0; index < locals_size; index++) {
                yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_program_node_t *)node)->locals.ids[index]));
            }
            yp_serialize_node(parser, (yp_node_t *)((yp_program_node_t *)node)->statements, buffer);
            break;
        }
        case YP_NODE_RANGE_NODE: {
            if (((yp_range_node_t *)node)->left == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_range_node_t *)node)->left, buffer);
            }
            if (((yp_range_node_t *)node)->right == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_range_node_t *)node)->right, buffer);
            }
            serialize_location(parser, &((yp_range_node_t *)node)->operator_loc, buffer);
            yp_buffer_append_u32(buffer, ((yp_range_node_t *)node)->flags);
            break;
        }
        case YP_NODE_RATIONAL_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_rational_node_t *)node)->numeric, buffer);
            break;
        }
        case YP_NODE_REDO_NODE: {
            break;
        }
        case YP_NODE_REGULAR_EXPRESSION_NODE: {
            serialize_location(parser, &((yp_regular_expression_node_t *)node)->opening_loc, buffer);
            serialize_location(parser, &((yp_regular_expression_node_t *)node)->content_loc, buffer);
            serialize_location(parser, &((yp_regular_expression_node_t *)node)->closing_loc, buffer);
            uint32_t unescaped_length = yp_ulong_to_u32(yp_string_length(&((yp_regular_expression_node_t *)node)->unescaped));
            yp_buffer_append_u32(buffer, unescaped_length);
            yp_buffer_append_str(buffer, yp_string_source(&((yp_regular_expression_node_t *)node)->unescaped), unescaped_length);
            yp_buffer_append_u32(buffer, ((yp_regular_expression_node_t *)node)->flags);
            break;
        }
        case YP_NODE_REQUIRED_DESTRUCTURED_PARAMETER_NODE: {
            uint32_t parameters_size = yp_ulong_to_u32(((yp_required_destructured_parameter_node_t *)node)->parameters.size);
            yp_buffer_append_u32(buffer, parameters_size);
            for (uint32_t index = 0; index < parameters_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_required_destructured_parameter_node_t *)node)->parameters.nodes[index], buffer);
            }
            serialize_location(parser, &((yp_required_destructured_parameter_node_t *)node)->opening_loc, buffer);
            serialize_location(parser, &((yp_required_destructured_parameter_node_t *)node)->closing_loc, buffer);
            break;
        }
        case YP_NODE_REQUIRED_PARAMETER_NODE: {
            yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_required_parameter_node_t *)node)->constant_id));
            break;
        }
        case YP_NODE_RESCUE_MODIFIER_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_rescue_modifier_node_t *)node)->expression, buffer);
            serialize_location(parser, &((yp_rescue_modifier_node_t *)node)->keyword_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_rescue_modifier_node_t *)node)->rescue_expression, buffer);
            break;
        }
        case YP_NODE_RESCUE_NODE: {
            serialize_location(parser, &((yp_rescue_node_t *)node)->keyword_loc, buffer);
            uint32_t exceptions_size = yp_ulong_to_u32(((yp_rescue_node_t *)node)->exceptions.size);
            yp_buffer_append_u32(buffer, exceptions_size);
            for (uint32_t index = 0; index < exceptions_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_rescue_node_t *)node)->exceptions.nodes[index], buffer);
            }
            if (((yp_rescue_node_t *)node)->operator_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_rescue_node_t *)node)->operator_loc, buffer);
            }
            if (((yp_rescue_node_t *)node)->exception == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_rescue_node_t *)node)->exception, buffer);
            }
            if (((yp_rescue_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_rescue_node_t *)node)->statements, buffer);
            }
            if (((yp_rescue_node_t *)node)->consequent == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_rescue_node_t *)node)->consequent, buffer);
            }
            break;
        }
        case YP_NODE_REST_PARAMETER_NODE: {
            serialize_location(parser, &((yp_rest_parameter_node_t *)node)->operator_loc, buffer);
            if (((yp_rest_parameter_node_t *)node)->name_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_rest_parameter_node_t *)node)->name_loc, buffer);
            }
            break;
        }
        case YP_NODE_RETRY_NODE: {
            break;
        }
        case YP_NODE_RETURN_NODE: {
            serialize_location(parser, &((yp_return_node_t *)node)->keyword_loc, buffer);
            if (((yp_return_node_t *)node)->arguments == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_return_node_t *)node)->arguments, buffer);
            }
            break;
        }
        case YP_NODE_SELF_NODE: {
            break;
        }
        case YP_NODE_SINGLETON_CLASS_NODE: {
            uint32_t locals_size = yp_ulong_to_u32(((yp_singleton_class_node_t *)node)->locals.size);
            yp_buffer_append_u32(buffer, locals_size);
            for (uint32_t index = 0; index < locals_size; index++) {
                yp_buffer_append_u32(buffer, yp_ulong_to_u32(((yp_singleton_class_node_t *)node)->locals.ids[index]));
            }
            serialize_location(parser, &((yp_singleton_class_node_t *)node)->class_keyword_loc, buffer);
            serialize_location(parser, &((yp_singleton_class_node_t *)node)->operator_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_singleton_class_node_t *)node)->expression, buffer);
            if (((yp_singleton_class_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_singleton_class_node_t *)node)->statements, buffer);
            }
            serialize_location(parser, &((yp_singleton_class_node_t *)node)->end_keyword_loc, buffer);
            break;
        }
        case YP_NODE_SOURCE_ENCODING_NODE: {
            break;
        }
        case YP_NODE_SOURCE_FILE_NODE: {
            uint32_t filepath_length = yp_ulong_to_u32(yp_string_length(&((yp_source_file_node_t *)node)->filepath));
            yp_buffer_append_u32(buffer, filepath_length);
            yp_buffer_append_str(buffer, yp_string_source(&((yp_source_file_node_t *)node)->filepath), filepath_length);
            break;
        }
        case YP_NODE_SOURCE_LINE_NODE: {
            break;
        }
        case YP_NODE_SPLAT_NODE: {
            serialize_location(parser, &((yp_splat_node_t *)node)->operator_loc, buffer);
            if (((yp_splat_node_t *)node)->expression == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_splat_node_t *)node)->expression, buffer);
            }
            break;
        }
        case YP_NODE_STATEMENTS_NODE: {
            uint32_t body_size = yp_ulong_to_u32(((yp_statements_node_t *)node)->body.size);
            yp_buffer_append_u32(buffer, body_size);
            for (uint32_t index = 0; index < body_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_statements_node_t *)node)->body.nodes[index], buffer);
            }
            break;
        }
        case YP_NODE_STRING_CONCAT_NODE: {
            yp_serialize_node(parser, (yp_node_t *)((yp_string_concat_node_t *)node)->left, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_string_concat_node_t *)node)->right, buffer);
            break;
        }
        case YP_NODE_STRING_NODE: {
            if (((yp_string_node_t *)node)->opening_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_string_node_t *)node)->opening_loc, buffer);
            }
            serialize_location(parser, &((yp_string_node_t *)node)->content_loc, buffer);
            if (((yp_string_node_t *)node)->closing_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_string_node_t *)node)->closing_loc, buffer);
            }
            uint32_t unescaped_length = yp_ulong_to_u32(yp_string_length(&((yp_string_node_t *)node)->unescaped));
            yp_buffer_append_u32(buffer, unescaped_length);
            yp_buffer_append_str(buffer, yp_string_source(&((yp_string_node_t *)node)->unescaped), unescaped_length);
            break;
        }
        case YP_NODE_SUPER_NODE: {
            serialize_location(parser, &((yp_super_node_t *)node)->keyword_loc, buffer);
            if (((yp_super_node_t *)node)->lparen_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_super_node_t *)node)->lparen_loc, buffer);
            }
            if (((yp_super_node_t *)node)->arguments == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_super_node_t *)node)->arguments, buffer);
            }
            if (((yp_super_node_t *)node)->rparen_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_super_node_t *)node)->rparen_loc, buffer);
            }
            if (((yp_super_node_t *)node)->block == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_super_node_t *)node)->block, buffer);
            }
            break;
        }
        case YP_NODE_SYMBOL_NODE: {
            if (((yp_symbol_node_t *)node)->opening_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_symbol_node_t *)node)->opening_loc, buffer);
            }
            serialize_location(parser, &((yp_symbol_node_t *)node)->value_loc, buffer);
            if (((yp_symbol_node_t *)node)->closing_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_symbol_node_t *)node)->closing_loc, buffer);
            }
            uint32_t unescaped_length = yp_ulong_to_u32(yp_string_length(&((yp_symbol_node_t *)node)->unescaped));
            yp_buffer_append_u32(buffer, unescaped_length);
            yp_buffer_append_str(buffer, yp_string_source(&((yp_symbol_node_t *)node)->unescaped), unescaped_length);
            break;
        }
        case YP_NODE_TRUE_NODE: {
            break;
        }
        case YP_NODE_UNDEF_NODE: {
            uint32_t names_size = yp_ulong_to_u32(((yp_undef_node_t *)node)->names.size);
            yp_buffer_append_u32(buffer, names_size);
            for (uint32_t index = 0; index < names_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_undef_node_t *)node)->names.nodes[index], buffer);
            }
            serialize_location(parser, &((yp_undef_node_t *)node)->keyword_loc, buffer);
            break;
        }
        case YP_NODE_UNLESS_NODE: {
            serialize_location(parser, &((yp_unless_node_t *)node)->keyword_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_unless_node_t *)node)->predicate, buffer);
            if (((yp_unless_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_unless_node_t *)node)->statements, buffer);
            }
            if (((yp_unless_node_t *)node)->consequent == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_unless_node_t *)node)->consequent, buffer);
            }
            if (((yp_unless_node_t *)node)->end_keyword_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_unless_node_t *)node)->end_keyword_loc, buffer);
            }
            break;
        }
        case YP_NODE_UNTIL_NODE: {
            serialize_location(parser, &((yp_until_node_t *)node)->keyword_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_until_node_t *)node)->predicate, buffer);
            if (((yp_until_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_until_node_t *)node)->statements, buffer);
            }
            break;
        }
        case YP_NODE_WHEN_NODE: {
            serialize_location(parser, &((yp_when_node_t *)node)->keyword_loc, buffer);
            uint32_t conditions_size = yp_ulong_to_u32(((yp_when_node_t *)node)->conditions.size);
            yp_buffer_append_u32(buffer, conditions_size);
            for (uint32_t index = 0; index < conditions_size; index++) {
                yp_serialize_node(parser, (yp_node_t *) ((yp_when_node_t *)node)->conditions.nodes[index], buffer);
            }
            if (((yp_when_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_when_node_t *)node)->statements, buffer);
            }
            break;
        }
        case YP_NODE_WHILE_NODE: {
            serialize_location(parser, &((yp_while_node_t *)node)->keyword_loc, buffer);
            yp_serialize_node(parser, (yp_node_t *)((yp_while_node_t *)node)->predicate, buffer);
            if (((yp_while_node_t *)node)->statements == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_while_node_t *)node)->statements, buffer);
            }
            break;
        }
        case YP_NODE_X_STRING_NODE: {
            serialize_location(parser, &((yp_x_string_node_t *)node)->opening_loc, buffer);
            serialize_location(parser, &((yp_x_string_node_t *)node)->content_loc, buffer);
            serialize_location(parser, &((yp_x_string_node_t *)node)->closing_loc, buffer);
            uint32_t unescaped_length = yp_ulong_to_u32(yp_string_length(&((yp_x_string_node_t *)node)->unescaped));
            yp_buffer_append_u32(buffer, unescaped_length);
            yp_buffer_append_str(buffer, yp_string_source(&((yp_x_string_node_t *)node)->unescaped), unescaped_length);
            break;
        }
        case YP_NODE_YIELD_NODE: {
            serialize_location(parser, &((yp_yield_node_t *)node)->keyword_loc, buffer);
            if (((yp_yield_node_t *)node)->lparen_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_yield_node_t *)node)->lparen_loc, buffer);
            }
            if (((yp_yield_node_t *)node)->arguments == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_serialize_node(parser, (yp_node_t *)((yp_yield_node_t *)node)->arguments, buffer);
            }
            if (((yp_yield_node_t *)node)->rparen_loc.start == NULL) {
                yp_buffer_append_u8(buffer, 0);
            } else {
                yp_buffer_append_u8(buffer, 1);
                serialize_location(parser, &((yp_yield_node_t *)node)->rparen_loc, buffer);
            }
            break;
        }
    }
}

void
yp_serialize_content(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer) {
    // First, serialize the encoding of the parser.
    size_t encoding_length = strlen(parser->encoding.name);
    yp_buffer_append_u32(buffer, yp_ulong_to_u32(encoding_length));
    yp_buffer_append_str(buffer, parser->encoding.name, encoding_length);

    // Here we're going to leave space for the offset of the constant pool in
    // the buffer.
    size_t offset = buffer->length;
    yp_buffer_append_zeroes(buffer, 4);

    // Next, encode the length of the constant pool.
    yp_buffer_append_u32(buffer, yp_ulong_to_u32(parser->constant_pool.size));

    // Now we're going to serialize the content of the node.
    yp_serialize_node(parser, node, buffer);

    // Now we're going to serialize the offset of the constant pool back where
    // we left space for it.
    uint32_t length = yp_ulong_to_u32(buffer->length);
    memcpy(buffer->value + offset, &length, sizeof(uint32_t));

    // Now we're going to serialize the constant pool.
    offset = buffer->length;
    yp_buffer_append_zeroes(buffer, parser->constant_pool.size * 8);

    yp_constant_t *constant;
    for (size_t index = 0; index < parser->constant_pool.capacity; index++) {
        constant = &parser->constant_pool.constants[index];

        // If we find a constant at this index, serialize it at the correct
        // index in the buffer.
        if (constant->id != 0) {
            size_t buffer_offset = offset + ((constant->id - 1) * 8);

            uint32_t source_offset = yp_long_to_u32(constant->start - parser->start);
            uint32_t constant_length = yp_ulong_to_u32(constant->length);

            memcpy(buffer->value + buffer_offset, &source_offset, 4);
            memcpy(buffer->value + buffer_offset + 4, &constant_length, 4);
        }
    }
}
